package local.blueheart.data.springdatademo.service.impl;

import local.blueheart.data.springdatademo.domain.archive.ArchiveData;
import local.blueheart.data.springdatademo.domain.archive.ArchiveIndexData;
import local.blueheart.data.springdatademo.domain.archive.ArchivedServerDBData;
import local.blueheart.data.springdatademo.domain.config.ApplicationDO;
import local.blueheart.data.springdatademo.domino.*;
import local.blueheart.data.springdatademo.exception.DominoException;
import local.blueheart.data.springdatademo.exception.DominoExcpetionHandler;
import local.blueheart.data.springdatademo.repository.archive.ArchiveDataRepository;
import local.blueheart.data.springdatademo.repository.archive.ArchiveIndexRepository;
import local.blueheart.data.springdatademo.service.ArchiveDataService;
import local.blueheart.data.springdatademo.util.mht.MHTHelper;
import local.blueheart.data.springdatademo.util.mht.MHTTransferException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@Service("archiveDataService")
@Scope("prototype")
public class ArchiveDataServiceImpl implements ArchiveDataService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveDataServiceImpl.class);

    @Value("${dataprofiling.basePath}")
    private String basePath;

    @Value("${dataprofiling.baseHttpURL}")
    private String baseHttpURL;

    @Autowired
    private ArchiveDataRepository archiveDataRepository;

    @Autowired
    private ArchiveIndexRepository archiveIndexRepository;

    private ArchivedServerDBData archivedServerDBData;

    private ApplicationDO applicationDO;

    //默认启动
    private AtomicBoolean atomicBoolean = new AtomicBoolean(true);


    public ArchiveDataServiceImpl() {
    }


    private void executeDataArchive() {
        DSession dSession = null;
        DDatabase dDatabase = null;
        DView dView = null;
        DDocument dDocument = null;
        DDocument tempDocument = null;
        MHTHelper mhtHelper = null;
        while (atomicBoolean.get() == true) {
            List<ArchiveIndexData> waitArchiveList = getArchivedIndexData();
            if (waitArchiveList.isEmpty()) {
                atomicBoolean.set(false);
                LOGGER.info("本模块 {} {} 所有数据已经归档完成", archivedServerDBData.getServerName(), archivedServerDBData.getDbPathName());
                break;
            }
            try {
                dSession = DSession.sessionFactory(archivedServerDBData.getServerName(), archivedServerDBData.getApplicationDO().getUserName(), archivedServerDBData.getApplicationDO().getPassWord());
                dDatabase = dSession.getDatabase("", archivedServerDBData.getDbPathName());
                mhtHelper = new MHTHelper(archivedServerDBData.getServerName(), archivedServerDBData.getApplicationDO().getUserName(), archivedServerDBData.getApplicationDO().getPassWord());
                Iterator<ArchiveIndexData> iterable = waitArchiveList.iterator();
                while (iterable.hasNext() && atomicBoolean.get() == true) {
                    ArchiveIndexData data = iterable.next();
                    dDocument = dDatabase.getDocument(data.getDocUniversalId());
                    if (!dDocument.isNull()) {
                        //执行文档相关操作
                        //生成ArchiveData
                        ArchiveData saveData = DDocumentHelper.getArchiveData(dDocument, archivedServerDBData.getModuleDO().getItemDOList());
                        saveData.setServerName(archivedServerDBData.getServerName());
                        saveData.setDbPath(archivedServerDBData.getDbPathName());
                        //生成MHT
                        String docURL = DDocumentHelper.getDocumentHTMLUrl(archivedServerDBData.getServerName(), archivedServerDBData.getDbPathName(), dDocument);
                        //docURL,请求编码
                        String docSavePath = DDocumentHelper.getDocumentSavePath(basePath, archivedServerDBData.getDbPathName(), dDocument);
                        String docFileName = DDocumentHelper.getDocumentFileName(dDocument);
                        mhtHelper.packArchivedMht(docURL, archivedServerDBData.getDbPathName(), docSavePath, "GB2312", docFileName, true);
                        //存储MHT
                        //1.生成的URL = baseURL+dbPath+docId+docid.mht
                        String accessURL = "";
                        saveData.setUrl(accessURL);
                        //归档数据
                        archiveDataRepository.save(saveData);
                        data.setStatus("1");
                        archiveIndexRepository.save(data);
                        //更新文档
                        dDocument.recycle();
                    }
                }
            } catch (DominoException de) {
                LOGGER.error("启动归档模块出错", de);
                DominoExcpetionHandler.handler(de);
            } catch (MHTTransferException e) {
                LOGGER.error("转换MHT出错",e);
                //DominoExcpetionHandler.handler(e);
            } finally {
                if (dDocument != null) {
                    dDocument.recycle();
                }
                if (dDatabase != null) {
                    dDatabase.recycle();
                }
                if (dSession != null) {
                    dSession.recycle();
                }

            }
        }
    }

    @Override
    public void startArchive() {
        atomicBoolean.set(true);
        executeDataArchive();
    }

    @Override
    public void stopArchive() {
        atomicBoolean.set(false);
    }


    @Override
    public void run() {
        startArchive();
    }

    public List<ArchiveIndexData> getArchivedIndexData() {
        return archiveIndexRepository.findByMainDocumentServerAndDbPathAndModuleDOAndStatus(archivedServerDBData.getServerName(), archivedServerDBData.getDbPathName(), archivedServerDBData.getModuleDO(), "0");
    }

    public ArchivedServerDBData getArchivedServerDBData() {
        return archivedServerDBData;
    }

    public void setArchivedServerDBData(ArchivedServerDBData archivedServerDBData) {
        this.archivedServerDBData = archivedServerDBData;
    }

    public ApplicationDO getApplicationDO() {
        return applicationDO;
    }

    public void setApplicationDO(ApplicationDO applicationDO) {
        this.applicationDO = applicationDO;
    }
}
